package by.wind.drebedengi.datalayer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
import java.util.Map.Entry;

import by.wind.drebedengi.datalayer.bean.Category;

public class GetCategoryList extends AbstractAction{

	public static final String SOAP_ACTION = "getCategoryList";
	public static final String METHOD_NAME = "getCategoryList";
	
	public static final String ID = "id";
	public static final String PARENT_ID = "parent_id";
	public static final String BUDGET_FAMILY_ID = "budget_family_id";
	public static final String TYPE = "type";
	public static final String NAME = "name";
	public static final String HIDDEN = "is_hidden";
	public static final String SORT = "sort";
	
	private ArrayList<Category> itsCategoryList = new ArrayList<Category>();
	
	@Override
	public void loadData() throws Exception{
		// TODO Auto-generated method stub
		HashMap<String, Object> propertyList = new HashMap<String, Object>();
		propertyList.put(Constants.API_ID_KEY, Constants.API_ID_VALUE);
		propertyList.put(Constants.LOGIN_KEY, Constants.LOGIN_VALUE);
		propertyList.put(Constants.PASS_KEY, Constants.PASS_VALUE);

		Vector<Hashtable<String,String>> itsData = (Vector<Hashtable<String,String>>) loadData(METHOD_NAME, SOAP_ACTION, propertyList);
		if (itsData != null)
		{
			for (Hashtable<String,String> element : itsData) {
				itsCategoryList.add(convertHashtableToCurrency(element));
			
			}
			itsCategoryList = sort();
		}
	}
	
	public Category convertHashtableToCurrency(Hashtable<String,String> element) {
		Category categoryElement = new Category();
		
		
		Iterator<Entry<String, String>> iterator = element.entrySet().iterator();
		 while(iterator.hasNext()) {
			
			String key = iterator.next().getKey();
			String value = element.get(key);
			if (key.equals(ID)) {
				categoryElement.setServer_id(Integer.parseInt(value));
			} else if (key.equals(PARENT_ID)) {
				categoryElement.setParentId(Integer.parseInt(value));
			} else if (key.equals(BUDGET_FAMILY_ID)) {
				categoryElement.setBudgetFamilyId(Integer.parseInt(value));
			} else if (key.equals(TYPE)) {
				categoryElement.setType(value);
			} else if (key.equals(NAME)) {
				categoryElement.setName(value);
			} else if (key.equals(HIDDEN)) {
				if (value.equals("t"))
					categoryElement.setHidden(true);
			} else if (key.equals(SORT)) {
				if (value.equals("t"))
					categoryElement.setSort(value);
			}
			
		}
		
		return categoryElement;
}
	
	private ArrayList<Category> sort() {
		ArrayList<Category> result = new ArrayList<Category>();
		for(Category element: itsCategoryList) {
			boolean isAdded = false;
			for(int pos = 0; pos < result.size() ; pos++) {
				if (element.getParentId() == result.get(pos).getServer_id()) {
					// Get the last element
					if (pos != result.size()-1) {
					pos++;
					Category innerElement = result.get(pos);
					while (hasElement(result, innerElement, element.getParentId()) && pos != result.size()-1) {
						pos++;
						innerElement = result.get(pos);
					}
					result.add(pos,element);
					} else
						result.add(pos+1,element);
					isAdded = true;
					break;
				}
			}
			if (!isAdded)
				result.add(element);
		}
		
		for(int pos = 0; pos < result.size() ; pos ++) {
			Category recursive = result.get(pos);
			String prefix = "";
			while(getParentElement(result, recursive)!= null) {
				prefix = prefix + "    ";
				recursive = getParentElement(result, recursive);
			}
			result.get(pos).setName(prefix + result.get(pos).getName());
		}
		
		for(Category element : result) {
			System.out.println(element.getName());
		}
		
		return result;
	}
	
	private boolean hasElement(ArrayList<Category> result,
			Category element, int parentId) {
		while(element.getParentId() != 0) {
			boolean isFound = false;
			if (element.getParentId() == parentId) return true;
			for(Category el : result) {
				if (el.getServer_id() == element.getParentId()) {
					element = el;
					break;
				}
			}
			if (!isFound) break;
		}
		return false;
	}

	private Category getParentElement(ArrayList<Category> aCategory, Category anElement) {
		for(Category element : aCategory) {
			if (anElement.getParentId() == element.getServer_id()) {
				return element;
			}
		}
		return null;
	}
	
	
	public ArrayList<Category> getCategoryList() {
		return itsCategoryList;
	}
}
